<?php

class Stepback {

	const STEP_BACK_ARRAY_KEY = "_stepback_library";
	const DEBUG = FALSE;
	
	private $ci;

	public function __construct() {
		$this->ci =& get_instance();

		$this->ci->load->library("session");

		if (!$this->_is_initialized()) {
			$this->_initialize();
		}
	}

	/**
	 * Esta funcion sirve para comprobar si la libreria esta inicializada en el 
	 * objeto session.
	 *
	 * si se llama sin argumentos respondera true si la libreria esta inicializada
	 * si se llama con un argumento, respondera true si ademas de la libreria inicializada
	 * existe un registro dentro de ella para aquella llave.
	 *
	 * estas llaves se utilizan para rastrear las posiciones que el usuario 
	 * ha ido recorriendo en la pagina. 
	 *
	 */
	private function _is_initialized($key = FALSE) {
		$internal_array = $this->ci->session->userdata(self::STEP_BACK_ARRAY_KEY);

		if ($internal_array === FALSE) {

			if (self::DEBUG) {
				echo "stepback not initialized<br />";
			}

			return FALSE;
		}

		if (FALSE !== $key) {
			$initialized = isset($internal_array[$key]);

			if (self::DEBUG) {
				if ($initialized === FALSE) {
					echo "stepback " . $key . " NOT initialized<br />";
				} else {
					echo "stepback " . $key . " initialized<br />";
				}
			}

			return $initialized;

		}

		if (self::DEBUG) {
			echo "stepback initialized<br />";
		}

		return TRUE;
	}

	/**
	 * inicializa la libreria en el objeto session.
	 */
	private function _initialize($key = FALSE, $override = FALSE) {
		if (self::DEBUG) {
			echo "stepback->_initialize($key, $override)<br />";
		}

		$internal_array = $this->ci->session->userdata(self::STEP_BACK_ARRAY_KEY);
		if (FALSE === $internal_array) {
			$this->ci->session->set_userdata(self::STEP_BACK_ARRAY_KEY, array());
			$internal_array = $this->ci->session->userdata(self::STEP_BACK_ARRAY_KEY);
		} else {
			if (TRUE === $override) {
				$this->ci->session->set_userdata(self::STEP_BACK_ARRAY_KEY, array());
				$internal_array = $this->ci->session->userdata(self::STEP_BACK_ARRAY_KEY);
			}
		}

		if (FALSE !== $key) {
			if (!isset($internal_array[$key])) {
				$key_array = array();
				$internal_array[$key] = $key_array;

				$this->ci->session->set_userdata(self::STEP_BACK_ARRAY_KEY, $internal_array);
			} else {
				if (TRUE === $override) {
					$key_array = array();
					$internal_array[$key] = $key_array;

					$this->ci->session->set_userdata(self::STEP_BACK_ARRAY_KEY, $internal_array);
				}
			}
		}
	}

	/**
	 * retorna el array interno de la libreria
	 */
	private function _get_internal_array($key = FALSE) {
		if (self::DEBUG) {
			echo "stepback->_get_internal_array($key)<br \>";
		}

		$this->_initialize($key, FALSE);

		$internal_array = $this->ci->session->userdata(self::STEP_BACK_ARRAY_KEY);

		return $internal_array;
	}

	private function _set_internal_array($internal_array) {
		$this->ci->session->set_userdata(self::STEP_BACK_ARRAY_KEY, $internal_array);
	}

	public function put($controller = FALSE, $method = FALSE, $args = FALSE) {
		if (FALSE === $controller || $method === FALSE) {
			return FALSE; 
		}

		if (FALSE === $args) {
			return FALSE;
		}

		$key = $controller . "/" . $method;
		$internal_array =& $this->_get_internal_array($key);

		array_push($internal_array[$key], $args);

		$this->_set_internal_array($internal_array);

		if (self::DEBUG) {
			echo "pushed '$args' in '$key'. <br />";
		}

		return TRUE;
	}

	public function pop($controller = FALSE, $method = FALSE) {
		if (FALSE === $controller || $method === FALSE) {
			return FALSE; 
		}

		$key = $controller . "/" . $method;
		$internal_array = $this->_get_internal_array($key);

		if (empty($internal_array[$key])) {
			if (self::DEBUG) {
				echo "internal_array[$key] is empty. <br />";
			}

			return FALSE;
		}

		$val = array_pop($internal_array[$key]);

		if (self::DEBUG) {
			echo "internal_array[$key] poped $val. <br />";
		}

		return $val;
	}

}

/* EOF */
